package com.cssy.xxkj.logic.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.byd.acegiext.domain.User;
import com.cssy.xxkj.logic.contants.BillStatusUtil;
import com.cssy.xxkj.logic.contants.BillTypeConstant;
import com.cssy.xxkj.logic.contants.DocumentSatusUitl;
import com.cssy.xxkj.logic.dao.LogicWarehouseDetailsDAO;
import com.cssy.xxkj.logic.dao.LogicWarehouseInventoryDAO;
import com.cssy.xxkj.logic.dao.LogicWarehousePriceDAO;
import com.cssy.xxkj.logic.dao.LogicWarehousePriceDetailsDAO;
import com.cssy.xxkj.logic.dao.LogicWhCheckTaskDAO;
import com.cssy.xxkj.logic.entity.LogicWarehouseDetailsDO;
import com.cssy.xxkj.logic.entity.LogicWarehouseInventoryDO;
import com.cssy.xxkj.logic.entity.LogicWarehousePriceDO;
import com.cssy.xxkj.logic.entity.LogicWarehousePriceDetailsDO;
import com.cssy.xxkj.logic.entity.LogicWhCheckTaskDO;
import com.cssy.xxkj.logic.entity.vo.LogicMaterialBackBillTypeSelVO;
import com.cssy.xxkj.logic.entity.vo.LogicWarehouseInventoryVO;
import com.cssy.xxkj.logic.service.ILogicWarehouseInventoryService;
import com.cssy.xxkj.logic.service.ILogicWhCheckTaskService;
import com.cssy.xxkj.logic.util.FunctionalSwitch;
import com.cssy.yd.logic.util.MathUtil;
import com.plat.exception.SyBaseException;
import com.plat.helper.SearchCondition;
import com.plat.helper.SearchConditions;
import com.plat.helper.SearchResult;
import com.plat.util.ExcelUtil;
import com.plat.util.IDCodeTypeUtil;

@Service("logicWarehouseInventoryService")
public class LogicWarehouseInventoryServiceImpl implements ILogicWarehouseInventoryService{
	@Resource(name = "logicWarehouseInventoryDAO")
	private LogicWarehouseInventoryDAO logicWarehouseInventoryDAO;
	
//	@Resource(name="basicPlaceofstorageDAO")	
//	private BasicPlaceofstorageDAO basicPlaceofstorageDAO;
	
	@Resource(name = "logicWarehouseDetailsDAO")
	private LogicWarehouseDetailsDAO logicWarehouseDetailsDAO;
	
	@Resource(name = "logicWarehousePriceDAO")
	private LogicWarehousePriceDAO logicWarehousePriceDAO;
	
	@Resource(name = "logicWarehousePriceDetailsDAO")
	private LogicWarehousePriceDetailsDAO logicWarehousePriceDetailsDAO;
	
	@Resource(name = "logicWhCheckTaskDAO")
	private LogicWhCheckTaskDAO logicWhCheckTaskDAO;
	
	
	@Override
	public SearchResult findListByExample(SearchConditions scs)
			throws SyBaseException {
		SearchResult rs=new SearchResult(scs);
		List<LogicWarehouseInventoryDO>  list=logicWarehouseInventoryDAO.find(scs);
		rs.setRecordCount(logicWarehouseInventoryDAO.count(scs));
		rs.setResults(list);
		return rs;
	}

	@Override
	public Integer delete(String id, User user) throws SyBaseException {
		Integer i =logicWarehouseInventoryDAO.deleteLogicWarehouseInventoryDOByPrimaryKey(id);
		return i;
	}

	@Override
	public Integer update(LogicWarehouseInventoryDO t, User user) throws SyBaseException {
		t.setBizModifyName(user.getName());
		t.setBizCreatorDate(new Date());
		return logicWarehouseInventoryDAO.updateLogicWarehouseInventoryDO(t);
	}

	@Override
	public LogicWarehouseInventoryDO save(LogicWarehouseInventoryDO t, User user) throws SyBaseException {
		t.setBizModifyName(user.getName());
		t.setBizModifyDate(new Date());
		logicWarehouseInventoryDAO.insertLogicWarehouseInventoryDO(t);
		return t;
	}

	@Override
	public LogicWarehouseInventoryDO findListById(String id) throws SyBaseException {
		return logicWarehouseInventoryDAO.findLogicWarehouseInventoryDOByPrimaryKey(id);
	}
	
	/**
	 * 更改库存
	 * @param t 存储有单据信息、物料信息及出入库数量的对象 . 
	 * <p>必填项: WhCode，Status，Jquantity，Batch，BillCode，BillType</p>
	 * <p>加权平均时必填：Price,Code,Unit,</p>
	 * @param user 包含当前登录用户信息的对象
	 * @param isUpdateCost 标识是否更改平均单价--加权平均
	 * @return
	 */
	@Override
	public boolean updateWhAffstockQuantity(LogicWarehouseDetailsDO t, User user, boolean isUpdateCost) throws SyBaseException{
		SearchConditions scs = new SearchConditions();
		scs.clearCondition();
		if(FunctionalSwitch.isISBATCH()){
			if(StringUtils.isBlank(t.getZd019Batch())){
				throw new SyBaseException("错误:物料批次不能为空!!");
			}
			scs.addCondition("zd020Batch",t.getZd019Batch(),SearchCondition.OP_EQUAL);
		}
		if(FunctionalSwitch.isISRANK()){
			if(StringUtils.isBlank(t.getZd012Status())){
				throw new SyBaseException("错误:未填写物料状态信息!!");
			}
		}
        if(FunctionalSwitch.isISSTORAGE()){
        	if(StringUtils.isBlank(t.getZd004WhPositionCode())){//仓位
        		throw new SyBaseException("错误:未填写仓位信息!!");
    		}
        	scs.addCondition("zd002WhLocationCode",t.getZd004WhPositionCode(),SearchCondition.OP_EQUAL);
        }
        if(StringUtils.isBlank(t.getZd003WhCode())){
			throw new SyBaseException("错误:未填写操作仓库信息!!");
		}
		if(t.getZd011BasicQuantity() == null){
			throw new SyBaseException("错误:物料库存更改数量不能为空!!");
		}
		//查询是否有物料记录:根据物料编号、型号、规则、材质、做法(颜色)、piCode
		//编号
		String keyStr = t.getZd005MaterialsCode();
		scs.addCondition("zd004MaterialsCode", t.getZd005MaterialsCode(),SearchCondition.OP_EQUAL);
		//名称
		if(StringUtils.isNotBlank(t.getZd005MaterialsName())){
			keyStr=keyStr+"_"+t.getZd005MaterialsName();
			scs.addCondition("zd005MaterialsName", t.getZd005MaterialsName(), SearchCondition.OP_EQUAL);
		}else{
			keyStr = keyStr +"_"+null;
		}
		
		//规格
		if(StringUtils.isNotBlank(t.getZd006MaterialsSpec())){
			keyStr = keyStr +"_"+t.getZd006MaterialsSpec();
			scs.addCondition("zd006MaterialsSpec", t.getZd006MaterialsSpec(), SearchCondition.OP_EQUAL);
		}else{
			keyStr = keyStr +"_"+null;
		}
		//型号
		if(StringUtils.isNotBlank(t.getZd007MaterialsModel())){
			keyStr = keyStr +"_"+t.getZd007MaterialsModel();
			scs.addCondition("zd007MaterialsModel", t.getZd007MaterialsModel(), SearchCondition.OP_EQUAL);
		}else{
			keyStr = keyStr +"_"+null;
		}
		//颜色
		if(StringUtils.isNotBlank(t.getZd008MaterialsColor())){
			keyStr = keyStr +"_"+t.getZd008MaterialsColor();
			scs.addCondition("zd008MaterialsColor", t.getZd008MaterialsColor(), SearchCondition.OP_EQUAL);
		}else{
			keyStr = keyStr +"_"+null;
		}
		//材质
		if(StringUtils.isNotBlank(t.getZd008MaterialsQuanlity())){
			keyStr = keyStr +"_"+t.getZd008MaterialsQuanlity();
			scs.addCondition("zd008MaterialsQuanlity", t.getZd008MaterialsQuanlity(), SearchCondition.OP_EQUAL);
		}else{
			keyStr = keyStr +"_"+null;
		}
		//pIcode
		if(StringUtils.isNotBlank(t.getZd020PiCode())){
			keyStr = keyStr +"_"+t.getZd020PiCode();
			scs.addCondition("zd026PiCode", t.getZd020PiCode(), SearchCondition.OP_EQUAL);
		}else{
			keyStr = keyStr +"_"+null;
		}
		scs.addCondition("zd001WhCode",t.getZd003WhCode(),SearchCondition.OP_EQUAL);
		scs.setRemovedProperty(null);
		List<LogicWarehouseInventoryDO> lgwhList = logicWarehouseInventoryDAO.find(scs);
		if(lgwhList==null){
			lgwhList = new ArrayList<LogicWarehouseInventoryDO>();
		}
		//组装成map对象
		Map<String, LogicWarehouseInventoryDO> lgwhMap= new HashMap<String, LogicWarehouseInventoryDO>();
		for(LogicWarehouseInventoryDO lgwh : lgwhList){
			if(lgwh==null||StringUtils.isBlank(lgwh.getId())){
				continue;
			}
			//编号
			String keyStrEx = lgwh.getZd004MaterialsCode();
			//名称
			String keyStrName=lgwh.getZd005MaterialsName();
			if(StringUtils.isNotBlank(keyStrName)){
				keyStrEx=keyStrEx+"_"+keyStrName;
			}else{
				keyStrEx = keyStrEx +"_"+ null;
			}
			//规则
			String zdSpec = lgwh.getZd006MaterialsSpec();
			if(StringUtils.isNotBlank(zdSpec)){
				keyStrEx = keyStrEx +"_"+ zdSpec;
			}else{
				keyStrEx = keyStrEx +"_"+ null;
			}
			//型号
			String zdModel = lgwh.getZd007MaterialsModel();
			if(StringUtils.isNotBlank(zdModel)){
				keyStrEx = keyStrEx +"_"+ zdModel;
			}else{
				keyStrEx = keyStrEx +"_"+ null;
			}
			//颜色
			String zdColor = lgwh.getZd008MaterialsColor();
			if(StringUtils.isNotBlank(zdColor)){
				keyStrEx = keyStrEx +"_"+ zdColor;
			}else{
				keyStrEx = keyStrEx +"_"+ null;
			}
			//材质
			String zdQuanlity = lgwh.getZd008MaterialsQuanlity();
			if(StringUtils.isNotBlank(zdQuanlity)){
				keyStrEx = keyStrEx +"_"+ zdQuanlity;
			}else{
				keyStrEx = keyStrEx +"_"+ null;
			}
			//piCode
			String zdPiCode = lgwh.getZd026PiCode();
			if(StringUtils.isNotBlank(zdPiCode)){
				keyStrEx = keyStrEx +"_"+ zdPiCode;
			}else{
				keyStrEx = keyStrEx +"_"+ null;
			}
			lgwhMap.put(keyStrEx, lgwh);
		}
		LogicWarehouseInventoryDO lgwhEx = lgwhMap.get(keyStr);
		if(lgwhMap==null||lgwhEx==null){
			if(t.getZd011BasicQuantity().compareTo(new BigDecimal(0))==-1){ //表示本次为出库操作
				throw new SyBaseException("错误：物料编码为："+t.getZd005MaterialsCode()+"在指定仓库仓位无库存信息！！");
			}
			//入库操作，新增库存信息
			LogicWarehouseInventoryDO lwd = this.changeLogicWhAffDOToLogicWarehouseInventoryDO(t);
			if(DocumentSatusUitl.ONE.equals(t.getZd012Status())){   //状态1：一等
				lwd.setZd019OneQuantity(t.getZd011BasicQuantity());
			}else if(DocumentSatusUitl.TWO.equals(t.getZd012Status())){  //状态2：次品
				lwd.setZd016DefectiveQuantity(t.getZd011BasicQuantity());
			}else if(DocumentSatusUitl.THREE.equals(t.getZd012Status())){  //状态3：旧货
				lwd.setZd017OldPartsQuantity(t.getZd011BasicQuantity());
			}else if(DocumentSatusUitl.FOUR.equals(t.getZd012Status())){//冻结库存
				lwd.setZd010BlockedStockQuantity(t.getZd011BasicQuantity());
			}else if(DocumentSatusUitl.FIVE.equals(t.getZd012Status())){//在途库存
				lwd.setZd011TravelingQuantity(t.getZd011BasicQuantity());
			}else{
				lwd.setZd009Quantity(t.getZd011BasicQuantity());
			}
			lwd.setZd028CustomerID(t.getZd022ConsumerID());
			lwd.setZd028CustomerCode(t.getZd022ConsumerCode());
			lwd.setZd028CustomerName(t.getZd022ConsumerName());
			lwd.setId(IDCodeTypeUtil.getId());
			lwd.setBizCreatorName(user.getName());
			lwd.setBizCreatorDate(new Date());
			this.logicWarehouseInventoryDAO.insertLogicWarehouseInventoryDO(lwd); //新增库存信息
		}else{
			BigDecimal subQuantity = new BigDecimal(0); //标识库存足不足
			//仓库物料的价格以最后一次为准
			if(isUpdateCost){
				lgwhEx.setZd024Price(t.getZd013Price());
				lgwhEx.setZd024StockPrice(t.getZd014StockPrice());
			}
			if(DocumentSatusUitl.ONE.equals(t.getZd012Status())){ //状态1：一等
				subQuantity = MathUtil.mathUtil.addtract(t.getZd011BasicQuantity(), lgwhEx.getZd019OneQuantity() == null ? new BigDecimal(0) : lgwhEx.getZd019OneQuantity());
				lgwhEx.setZd019OneQuantity(subQuantity);
			}else if(DocumentSatusUitl.TWO.equals(t.getZd012Status())){ //状态2：次品
				subQuantity = MathUtil.mathUtil.addtract(t.getZd011BasicQuantity(), lgwhEx.getZd016DefectiveQuantity() == null ? new BigDecimal(0) : lgwhEx.getZd016DefectiveQuantity());				
				lgwhEx.setZd016DefectiveQuantity(subQuantity);		
			}else if(DocumentSatusUitl.THREE.equals(t.getZd012Status())){//状态3：旧货
				subQuantity = MathUtil.mathUtil.addtract(t.getZd011BasicQuantity(), lgwhEx.getZd017OldPartsQuantity() == null ? new BigDecimal(0) : lgwhEx.getZd017OldPartsQuantity());			
				lgwhEx.setZd017OldPartsQuantity(subQuantity);			
			}else if(DocumentSatusUitl.FOUR.equals(t.getZd012Status())){//冻结库存
				subQuantity = MathUtil.mathUtil.addtract(t.getZd011BasicQuantity(), lgwhEx.getZd010BlockedStockQuantity() == null ? new BigDecimal(0) : lgwhEx.getZd010BlockedStockQuantity());			
				lgwhEx.setZd010BlockedStockQuantity(subQuantity);			
			}else if(DocumentSatusUitl.FIVE.equals(t.getZd012Status())){//在途库存
				subQuantity = MathUtil.mathUtil.addtract(t.getZd011BasicQuantity(), lgwhEx.getZd011TravelingQuantity() == null ? new BigDecimal(0) : lgwhEx.getZd011TravelingQuantity());			
				lgwhEx.setZd011TravelingQuantity(subQuantity);			
			}else{
				subQuantity = MathUtil.mathUtil.addtract(t.getZd011BasicQuantity(), lgwhEx.getZd009Quantity() == null ? new BigDecimal(0) : lgwhEx.getZd009Quantity());			
				lgwhEx.setZd009Quantity(subQuantity);	
			}
			if((subQuantity.compareTo(new BigDecimal(0)))==-1){
				throw new SyBaseException("错误：物料"+t.getZd005MaterialsCode()+"在指定仓库("+t.getZd004WhPositionCode()+")仓位库存，等级（"+t.getZd012Status()+"）不足！！缺少数量："+(subQuantity));
			}
			lgwhEx.setBizModifyName(user.getName());
			lgwhEx.setBizModifyDate(new Date());
			logicWarehouseInventoryDAO.updateLogicWarehouseInventoryDO(lgwhEx);//更新库存
		}
		//更改平均单价
		if (isUpdateCost){
			
			Map<String, Object> paramMap = new HashMap<String, Object>();
			//物料id、code、名称、型号、规格/型号、颜色、材质
			paramMap.put("zdMaterId", t.getZd005MaterialsId());
			paramMap.put("zdMaterCode", t.getZd005MaterialsCode());
			
			paramMap.put("zdMaterName", t.getZd005MaterialsName()==null?"":t.getZd005MaterialsName().trim());
			paramMap.put("zdMaterModel", t.getZd007MaterialsModel()==null?"":t.getZd007MaterialsModel().trim());
			paramMap.put("zdMaterSpec", t.getZd006MaterialsSpec()==null?"":t.getZd006MaterialsSpec().trim());
			paramMap.put("zdMaterColor", t.getZd008MaterialsColor()==null?"":t.getZd008MaterialsColor().trim());
			paramMap.put("zdMaterQuanlity", t.getZd008MaterialsQuanlity()==null?"":t.getZd008MaterialsQuanlity().trim());
			//仓库
			paramMap.put("whId", t.getZd003WhCode()==null?"":t.getZd003WhCode().trim());
			paramMap.put("whCode", t.getZd003WhCode()==null?"":t.getZd003WhCode().trim());
			paramMap.put("whName", t.getZd003WhName()==null?"":t.getZd003WhName().trim());
			//仓位信息
			if(FunctionalSwitch.isISSTORAGE()){
				paramMap.put("hubId", t.getZd004WhPositionId()==null?"":t.getZd004WhPositionId().trim());
				paramMap.put("hubCode", t.getZd004WhPositionCode()==null?"":t.getZd004WhPositionCode().trim());
				paramMap.put("hubName", t.getZd004WhPositionName()==null?"":t.getZd004WhPositionName().trim());
			}
			paramMap.put("price", t.getZd013Price());
			paramMap.put("quantity", t.getZd011BasicQuantity());
			paramMap.put("billType", t.getZd002BillType());
			
			BigDecimal sumQuantity = this.getSumQuantityByWhInfoAndMaterInfo(paramMap);
			if(BigDecimal.ZERO.compareTo(sumQuantity)==1){
				sumQuantity = BigDecimal.ZERO;
			}
			paramMap.put("hcsQuantity", sumQuantity);
			
			this.updateCostQuaAndPrice(paramMap, user, isUpdateCost);
		}
		//如果存在当前仓库存在月度盘点单据不得对其仓库做出入库操作
		scs.clearCondition();
		scs.addCondition("zd001WhCode", t.getZd003WhCode(),SearchCondition.OP_EQUAL);
		scs.addCondition("zd009BillType", BillStatusUtil.MONTHCHECK,SearchCondition.OP_EQUAL);
		scs.addCondition("zd003TaskStatus", BillStatusUtil.WH_CHECK_TASK_FOUR,
				SearchCondition.OP_NOTEQUAL);
		if(t.getZd002BillType().equals(BillTypeConstant.CHECKTASK)){
			scs.addCondition("zd002TaskCode", t.getZd001BillCode(),SearchCondition.OP_NOTEQUAL);
		}
		List<LogicWhCheckTaskDO> ctList=this.logicWhCheckTaskDAO.find(scs);
		if(!(ctList==null||ctList.isEmpty()||ctList.size()==0)){
			throw new SyBaseException("仓库存在未完成的月度盘点单据，不能对本仓库做出入库操作!!!!!!");
		}
		t.setId(IDCodeTypeUtil.getId());
		t.setBizCreatorName(user.getName());
		t.setBizCreatorDate(new Date());
		logicWarehouseDetailsDAO.insertLogicWarehouseDetailsDO(t); //插入出入库信息记录
		return true;
	}
	
	/**
	 * 转换对象
	 * @param t
	 * @return
	 */
	public LogicWarehouseInventoryDO changeLogicWhAffDOToLogicWarehouseInventoryDO(LogicWarehouseDetailsDO t){
		LogicWarehouseInventoryDO lwd = new LogicWarehouseInventoryDO();
		lwd.setZd020Batch(t.getZd019Batch() == null ? null : t.getZd019Batch());
		lwd.setZd001WhId(t.getZd003WhId());
		lwd.setZd001WhCode(t.getZd003WhCode() == null ? null : t.getZd003WhCode());
		lwd.setZd001WhName(t.getZd003WhName()==null?null:t.getZd003WhName());
		lwd.setZd002WhLocationId(t.getZd004WhPositionId());
		lwd.setZd002WhLocationCode(t.getZd004WhPositionCode() == null ? null : t.getZd004WhPositionCode());
		lwd.setZd002WhLocationName(t.getZd004WhPositionName() == null ? null : t.getZd004WhPositionName());
		lwd.setZd003MaterialsId(t.getZd005MaterialsId());
		lwd.setZd004MaterialsCode(t.getZd005MaterialsCode() == null ? null : t.getZd005MaterialsCode());
		lwd.setZd005MaterialsName(t.getZd005MaterialsName() == null ? null : t.getZd005MaterialsName());
		lwd.setZd006MaterialsSpec(t.getZd006MaterialsSpec() == null ? null : t.getZd006MaterialsSpec());
		lwd.setZd007MaterialsModel(t.getZd007MaterialsModel()==null?null:t.getZd007MaterialsModel());
		//add by gzy begin
		lwd.setZd008MaterialsQuanlity(t.getZd008MaterialsQuanlity()==null?null:t.getZd008MaterialsQuanlity());
		lwd.setZd008MaterialsColor(t.getZd008MaterialsColor()==null?null:t.getZd008MaterialsColor());
		lwd.setZd026PiCode(t.getZd020PiCode());
		//end 
		lwd.setZd024Price(t.getZd013Price() == null ? null : t.getZd013Price());
		lwd.setZd024StockPrice(t.getZd014StockPrice() == null ? null : t.getZd014StockPrice());
		lwd.setZd025Status(t.getZd012Status() == null ? null : t.getZd012Status());
		//lwd.setStockPrice(t.getZd014StockPrice() == null ? null : t.getZd014StockPrice());
		lwd.setZd008Unit(t.getZd009BasicUnit() == null ? null : t.getZd009BasicUnit());
		lwd.setZd022MaterialsProDate(t.getZd017MaterialsProDate()==null?null:t.getZd017MaterialsProDate());
		lwd.setZd023MaterialsValidityDate(t.getZd018MaterialsValidityDate()==null?null:t.getZd018MaterialsValidityDate());
		
		lwd.setZd028CustomerID(t.getZd022ConsumerID());
		lwd.setZd028CustomerCode(t.getZd022ConsumerCode());
		lwd.setZd028CustomerName(t.getZd022ConsumerName());
		return lwd;
	}
	
	/**
	 * 修改平均单价及总库存信息
	 * @param paramMap 入库物料信息(需包含物料编码、仓库编码、数量  可选仓位编码、价格)
	 * @param user 登录用户
	 * @return
	 * @throws SyBaseException
	 */
	//REQUIRED:业务方法需要在一个容器里运行。如果方法运行时，已经处在一个事务中，那么加入到这个事务，否则自己新建一个新的事务。
	@Transactional(propagation=Propagation.REQUIRED)
	private LogicWarehousePriceDO updateCostQuaAndPrice(Map<String, Object> paramMap,User user, boolean isUpdate)throws SyBaseException{
		
		BigDecimal zdQuantity = new BigDecimal(paramMap.get("quantity")+"");
		if(BigDecimal.ZERO.compareTo(zdQuantity)==1 || BigDecimal.ZERO.compareTo(zdQuantity)==0){
			//判断是否是出库，出库不能修改平均价
			throw new SyBaseException("本次单据类型为出库不能修改平均单价！！");
		}
		LogicWarehousePriceDO whprice = new LogicWarehousePriceDO();
		whprice.setZd001MaterialsId(paramMap.get("zdMaterId")+"");
		whprice.setZd001MaterialsCode(paramMap.get("zdMaterCode")+"");
		whprice.setZd001MaterialsName(paramMap.get("zdMaterName")==null?null:paramMap.get("zdMaterName")+"");
		whprice.setZd001MaterialsType(null);
		whprice.setZd001MaterialsModel(paramMap.get("zdMaterModel")==null?null:paramMap.get("zdMaterModel")+"");
		whprice.setZd001MaterialsSpec(paramMap.get("zdMaterSpec")==null?null:paramMap.get("zdMaterSpec")+"");
		whprice.setZd001MaterialsColor(paramMap.get("zdMaterColor")==null?null:paramMap.get("zdMaterColor")+"");
		whprice.setZd001MaterialsQuanlity(paramMap.get("zdMaterQuanlity")==null?null:paramMap.get("zdMaterQuanlity")+"");
		//查询平均单价及库存信息
		List<LogicWarehousePriceDO> lpdList = logicWarehousePriceDAO.findListByExample(whprice);
		whprice.setZd002WhId(paramMap.get("whId")==null?null:paramMap.get("whId")+"");
		whprice.setZd002WhCode(paramMap.get("whCode")==null?null:paramMap.get("whCode")+"");
		whprice.setZd003WhLocationId(paramMap.get("hubId")==null?null:paramMap.get("hubId")+"");
		whprice.setZd003WhLocationCode(paramMap.get("hubCode")==null?null:paramMap.get("hubCode")+"");
		whprice.setZd002WhName(paramMap.get("whName")==null?null:paramMap.get("whName")+"");
		whprice.setZd003WhLocationName(paramMap.get("hubName")==null?null:paramMap.get("hubName")+"");
		whprice.setZd004BillType(paramMap.get("billType")==null?null:paramMap.get("billType")+"");
		//获取本次入库单价
		BigDecimal inPrice = paramMap.get("price")== null?BigDecimal.ZERO:new BigDecimal(paramMap.get("price")+"");
		//获取本次入库数量
		BigDecimal inQuantity = paramMap.get("quantity")==null?BigDecimal.ZERO:new BigDecimal(paramMap.get("quantity")+""); 
		//获取剩余库存数量
		BigDecimal kcQuantity = paramMap.get("hcsQuantity")==null?BigDecimal.ZERO:new BigDecimal(paramMap.get("hcsQuantity")+""); 
		//单价
		whprice.setZd008Price(inPrice);
		//入库数量
		whprice.setZd005Quantity(inQuantity);
		if(lpdList==null||lpdList.isEmpty()||lpdList.size()==0){
			//没有单价信息，表示第一次入库
			whprice.setId(IDCodeTypeUtil.getId());
			if(isUpdate){
				whprice.setZd007SumPrice(inPrice);
			}else{
				whprice.setZd007SumPrice(BigDecimal.ZERO);
			}
			whprice.setZd006SumQuantity(inQuantity);
			whprice.setBizCreatorName(user.getName());
			whprice.setBizCreatorDate(new Date());
			logicWarehousePriceDAO.insertLogicWarehousePriceDO(whprice);
			//插入平均价的详细记录
			this.processPriceDetails(whprice, user);
		}else if(lpdList.size()==1){
			LogicWarehousePriceDO _lpd = lpdList.get(0);
			_lpd.setZd006SumQuantity(MathUtil.mathUtil.addtract((MathUtil.mathUtil.subtract(kcQuantity, inQuantity)), inQuantity));
			_lpd.setBizModifyName(user.getName());
			_lpd.setBizModifyDate(new Date());
			if(isUpdate){
				if(kcQuantity.compareTo(new BigDecimal(0))==1){
					//剩余总金额
					BigDecimal sumPrice = _lpd.getZd007SumPrice();
					BigDecimal cmpSumMoney = MathUtil.mathUtil.subtract(kcQuantity, inQuantity).multiply(sumPrice);
					//本次总金额
					BigDecimal theSumMoney = inQuantity.multiply(inPrice);
					//总数量
					BigDecimal countQuanity = _lpd.getZd006SumQuantity();
					//计算新的平均单价
					BigDecimal avgPrice = cmpSumMoney.add(theSumMoney).divide(countQuanity, 4, RoundingMode.HALF_DOWN);
					_lpd.setZd007SumPrice(avgPrice);
				}else{
					_lpd.setZd007SumPrice(new BigDecimal(0));
					_lpd.setZd006SumQuantity(new BigDecimal(0));
				}
				//更新库存信息及平均单价
				logicWarehousePriceDAO.updateLogicWarehousePriceDO(_lpd);
				//插入平均价的详细记录
				this.processPriceDetails(_lpd, user);
			}
		}else{
			throw new SyBaseException("物料有多条平均单价信息修改平均单价或库存异常！！");
		}
		return whprice;
	}
	
	//REQUIRED:业务方法需要在一个容器里运行。如果方法运行时，已经处在一个事务中，那么加入到这个事务，否则自己新建一个新的事务。
	@Transactional(propagation=Propagation.REQUIRED)
	private void processPriceDetails(LogicWarehousePriceDO lp, User user)throws SyBaseException{
		LogicWarehousePriceDetailsDO lpd = new LogicWarehousePriceDetailsDO();
		lpd.setZd001MaterialsId(lp.getZd001MaterialsId());
		lpd.setZd001MaterialsCode(lp.getZd001MaterialsCode());
		lpd.setZd001MaterialsType(lp.getZd001MaterialsType());
		lpd.setZd001MaterialsName(lp.getZd001MaterialsName());
		lpd.setZd001MaterialsModel(lp.getZd001MaterialsModel());
		lpd.setZd001MaterialsSpec(lp.getZd001MaterialsSpec());
		lpd.setZd001MaterialsColor(lp.getZd001MaterialsColor());
		lpd.setZd001MaterialsQuanlity(lp.getZd001MaterialsQuanlity());
		lpd.setZd002WhId(lp.getZd002WhId());
		lpd.setZd002WhCode(lp.getZd002WhCode());
		lpd.setZd002WhName(lp.getZd002WhName());
		lpd.setZd003WhLocationCode(lp.getZd003WhLocationCode());
		lpd.setZd003WhLocationId(lp.getZd003WhLocationId());
		lpd.setZd003WhLocationName(lp.getZd003WhLocationName());
		lpd.setZd004BillType(lp.getZd004BillType());
		lpd.setZd005Quantity(lp.getZd005Quantity());
		lpd.setZd006SumQuantity(lp.getZd006SumQuantity());
		lpd.setZd007SumPrice(lp.getZd007SumPrice());
		lpd.setZd008Price(lp.getZd008Price());
		lpd.setId(IDCodeTypeUtil.getId());
		lpd.setBizCreatorName(user.getName());
		lpd.setBizCreatorDate(new Date());
		logicWarehousePriceDetailsDAO.insertLogicWarehousePriceDetailsDO(lpd);
	}
	
	/**
	 * 列表显示库存信息
	 */
	@Override
	public SearchResult findForWareHouseStockByExample(SearchConditions scs)
			throws SyBaseException {
		SearchResult rs=new SearchResult(scs);
		List<LogicWarehouseInventoryVO>  list=logicWarehouseInventoryDAO.findForWareHouseStock(scs);
		rs.setRecordCount(logicWarehouseInventoryDAO.findForWareHouseStockCount(scs));
		rs.setResults(list);
		return rs;
	}
	
	/**
	 * 验证库存是否足够用于出库
	 * @param maCode 物料编码
	 * @param whCode 仓库编码 
	 * @param hubCode 仓位编码(无仓位参数定义为空)
	 * @param status 物料状态
	 * @param batch  批次(无批次参数定义为空)
	 * @param quaitity 本次出库数量
	 * @return
	 */
	@Override
	public boolean validateStorageQuaitity(String maCode , String whCode , 
			String hubCode ,String status, String batch , BigDecimal quantity) throws SyBaseException{
		
		SearchConditions scs = new SearchConditions();
		if(FunctionalSwitch.isISBATCH()){
			scs.addCondition("zd020Batch",batch,SearchCondition.OP_EQUAL);
		}
		if(FunctionalSwitch.isISSTORAGE()){
			scs.addCondition("zd002WhLocationCode",hubCode,SearchCondition.OP_EQUAL);
		}
		scs.addCondition("zd004MaterialsCode", maCode,SearchCondition.OP_EQUAL);
		scs.addCondition("zd001WhCode",whCode,SearchCondition.OP_EQUAL);
		scs.setRemovedProperty(null);
		SearchResult sr = this.findListByExample(scs);
		if(sr == null || sr.getResults() == null || sr.getResults().size() < 1){
			throw new SyBaseException("错误: 指定物品存储位置无此物品库存信息存在!!");
		}else if(sr != null && sr.getResults() != null && sr.getResults().size() > 1){
			throw new SyBaseException("错误: 指定物品存储位置有多条物品库存信息存在!!");
		}
		LogicWarehouseInventoryDO lwsd = (LogicWarehouseInventoryDO)sr.getResults().get(0);
		BigDecimal subQuantity = new BigDecimal(0); //标识库存足不足
		if(DocumentSatusUitl.ONE.equals(status)){ //status= 1 一等
			subQuantity = MathUtil.mathUtil.subtract(lwsd.getZd019OneQuantity() == null ? new BigDecimal(0) :lwsd.getZd019OneQuantity(), quantity);
		}else if(DocumentSatusUitl.TWO.equals(status)){ //status= 2 次品
			subQuantity = MathUtil.mathUtil.subtract(lwsd.getZd016DefectiveQuantity() == null ? new BigDecimal(0) : lwsd.getZd016DefectiveQuantity(), quantity);
		}else if(DocumentSatusUitl.THREE.equals(status)){ //status= 3旧品
			subQuantity = MathUtil.mathUtil.subtract(lwsd.getZd017OldPartsQuantity() == null ? new BigDecimal(0) : lwsd.getZd017OldPartsQuantity(), quantity);
		}else if(DocumentSatusUitl.FOUR.equals(status)){ //status= 3冻结库存
			subQuantity = MathUtil.mathUtil.subtract(lwsd.getZd010BlockedStockQuantity() == null ? new BigDecimal(0) : lwsd.getZd010BlockedStockQuantity(), quantity);
		}else if(DocumentSatusUitl.FIVE.equals(status)){ //status= 3在途库存
			subQuantity = MathUtil.mathUtil.subtract(lwsd.getZd011TravelingQuantity() == null ? new BigDecimal(0) : lwsd.getZd011TravelingQuantity(), quantity);
		}else{
			subQuantity = MathUtil.mathUtil.subtract(lwsd.getZd009Quantity()==null? new BigDecimal(0) : lwsd.getZd009Quantity(), quantity);
		}
		if((subQuantity.compareTo(new BigDecimal(0)))==-1){
			return false;
		}
		return true;
	}
	
	@Override
	public BigDecimal getStorageQuaitity(String maCode, String whCode,
			String hubCode, String status, String batch)
			throws SyBaseException {
		SearchConditions scs = new SearchConditions();
		if(FunctionalSwitch.isISBATCH()){
			scs.addCondition("zd020Batch",batch,SearchCondition.OP_EQUAL);
		}
		if(FunctionalSwitch.isISSTORAGE()){
			scs.addCondition("zd002WhLocationCode",hubCode,SearchCondition.OP_EQUAL);
		}
		scs.addCondition("zd004MaterialsCode", maCode,SearchCondition.OP_EQUAL);
		scs.addCondition("zd001WhCode",whCode,SearchCondition.OP_EQUAL);
		scs.setRemovedProperty(null);
		SearchResult sr = this.findListByExample(scs);
		BigDecimal subQuantity = new BigDecimal(0);
		if(sr == null || sr.getResults() == null || sr.getResults().size() < 1){
			return new BigDecimal(0);
		}else if(sr != null && sr.getResults() != null && sr.getResults().size() > 1){
			throw new SyBaseException("错误:指定位置处有多条库存信息!! 物料编码："+maCode+" 仓库编码："+whCode+" 仓位："+hubCode+"  批次："+batch);
		}
		LogicWarehouseInventoryDO lwsd = (LogicWarehouseInventoryDO)sr.getResults().get(0);
		if(DocumentSatusUitl.ONE.equals(status)){ //status= 1 一等
			if (lwsd.getZd019OneQuantity() != null)
				subQuantity = lwsd.getZd019OneQuantity();
		}else if(DocumentSatusUitl.TWO.equals(status)){ //status= 2 次品
			if (lwsd.getZd016DefectiveQuantity() != null)
				subQuantity = lwsd.getZd016DefectiveQuantity();
		}else if(DocumentSatusUitl.THREE.equals(status)){ //status= 3旧品
			if (lwsd.getZd017OldPartsQuantity() != null)
				subQuantity = lwsd.getZd017OldPartsQuantity();
		}else if(DocumentSatusUitl.FOUR.equals(status)){ //status= 3冻结库存
			if (lwsd.getZd010BlockedStockQuantity() != null)
				subQuantity = lwsd.getZd010BlockedStockQuantity();
		}else if(DocumentSatusUitl.FIVE.equals(status)){ //status= 3在途库存
			if (lwsd.getZd011TravelingQuantity() != null)
				subQuantity = lwsd.getZd011TravelingQuantity();
		}else{
			subQuantity=lwsd.getZd009Quantity();
		}
		return subQuantity;
	}
	
	@Override
	public Map<String,BigDecimal> getStorageQuaitityToMap(String piCode, String whCode,
			String hubCode, String batch)
			throws SyBaseException {
		SearchConditions scs = new SearchConditions();
		if(FunctionalSwitch.isISBATCH()){
			scs.addCondition("zd020Batch",batch,SearchCondition.OP_EQUAL);
		}
		if(FunctionalSwitch.isISSTORAGE()){
			scs.addCondition("zd002WhLocationCode",hubCode,SearchCondition.OP_EQUAL);
		}
		if(StringUtils.isNotBlank(whCode)){
			scs.addCondition("zd001WhCode",whCode,SearchCondition.OP_EQUAL);
		}
		scs.setRemovedProperty(null);
		SearchResult sr = this.findListByExample(scs);
		if(sr == null || sr.getResults() == null || sr.getResults().size() < 1){
			return null;
		}
		Map<String, BigDecimal> sgeQuantityMap = new HashMap<String, BigDecimal>();
		List<LogicWarehouseInventoryDO> lwsdList = sr.getResults();
		BigDecimal subQuantity = new BigDecimal(0);
		for(LogicWarehouseInventoryDO lwsd : lwsdList){
			if(lwsd==null||StringUtils.isBlank(lwsd.getId())){
				continue;
			}
			//pi 仓库编码   code name spec model  quanlity color
			String keyStr=(StringUtils.isEmpty(lwsd.getZd026PiCode())?null:lwsd.getZd026PiCode())+"_"+
							(StringUtils.isEmpty(lwsd.getZd001WhCode())?null:lwsd.getZd001WhCode())+"_"+
							(StringUtils.isEmpty(lwsd.getZd004MaterialsCode())?null:lwsd.getZd004MaterialsCode())+"_"+
							(StringUtils.isEmpty(lwsd.getZd005MaterialsName())?null:lwsd.getZd005MaterialsName())+"_"+
							(StringUtils.isEmpty(lwsd.getZd006MaterialsSpec())?null:lwsd.getZd006MaterialsSpec())+"_"+
							(StringUtils.isEmpty(lwsd.getZd007MaterialsModel())?null:lwsd.getZd007MaterialsModel())+"_"+
							(StringUtils.isEmpty(lwsd.getZd008MaterialsQuanlity())?null:lwsd.getZd008MaterialsQuanlity())+"_"+
							(StringUtils.isEmpty(lwsd.getZd008MaterialsColor())?null:lwsd.getZd008MaterialsColor());
			if(DocumentSatusUitl.ONE.equals(lwsd.getZd025Status())){ //status= 1 一等
				subQuantity = lwsd.getZd019OneQuantity()==null?BigDecimal.ZERO:lwsd.getZd019OneQuantity();
			}else if(DocumentSatusUitl.TWO.equals(lwsd.getZd025Status())){ //status= 2 次品
				subQuantity = lwsd.getZd016DefectiveQuantity()==null?BigDecimal.ZERO:lwsd.getZd016DefectiveQuantity();
			}else if(DocumentSatusUitl.THREE.equals(lwsd.getZd025Status())){ //status= 3旧品
				subQuantity = lwsd.getZd017OldPartsQuantity()==null?BigDecimal.ZERO:lwsd.getZd017OldPartsQuantity();
			}else if(DocumentSatusUitl.FOUR.equals(lwsd.getZd025Status())){ //status= 3冻结库存
				subQuantity = lwsd.getZd010BlockedStockQuantity()==null?BigDecimal.ZERO:lwsd.getZd010BlockedStockQuantity();
			}else if(DocumentSatusUitl.FIVE.equals(lwsd.getZd025Status())){ //status= 3在途库存
				subQuantity = lwsd.getZd011TravelingQuantity()==null?BigDecimal.ZERO:lwsd.getZd011TravelingQuantity();
			}else{
				subQuantity = lwsd.getZd009Quantity()==null?BigDecimal.ZERO:lwsd.getZd009Quantity();
			}
			if(sgeQuantityMap.get(keyStr)==null){
				sgeQuantityMap.put(keyStr, subQuantity);
			}else{
				sgeQuantityMap.put(keyStr, subQuantity.add(sgeQuantityMap.get(keyStr)));
			}
			subQuantity = BigDecimal.ZERO;
		}
		
		return sgeQuantityMap;
	}
	
	/**
	 * 查询物料在系统中的总数量
	 * @param paramMap
	 * @return
	 * @throws SyBaseException
	 */
	private BigDecimal getSumQuantityByWhInfoAndMaterInfo(Map<String, Object> paramMap)throws SyBaseException{
		if(paramMap==null){
			throw new SyBaseException("错误:物料id/编码为空，查询库存信息失败!!");
		}
		if(StringUtils.isBlank(paramMap.get("whCode")+"")){
			throw new SyBaseException("错误:仓库编码为空，查询库存信息失败!!");
		}
		BigDecimal sumQuantity = BigDecimal.ZERO;
		SearchConditions zdScs = new SearchConditions();
		String key="";//id code model spec color quanlity
		if(StringUtils.isNotBlank(paramMap.get("zdMaterId")+"")){
			zdScs.addCondition("zd003MaterialsId", paramMap.get("zdMaterId")+"", SearchCondition.OP_EQUAL);
			key=paramMap.get("zdMaterId")+"_";
		}else{
			key=null+"_";
		}
		if(StringUtils.isNotBlank(paramMap.get("zdMaterCode")+"")){
			zdScs.addCondition("zd004MaterialsCode", paramMap.get("zdMaterCode")+"", SearchCondition.OP_EQUAL);
			key=key+paramMap.get("zdMaterCode")+"_";
		}else{
			key=key+null+"_";
		}
		if(StringUtils.isNotBlank(paramMap.get("zdMaterModel")+"")){
			zdScs.addCondition("zd007MaterialsModel", paramMap.get("zdMaterModel")+"", SearchCondition.OP_EQUAL);
			key=key+paramMap.get("zdMaterModel")+"_";
		}else{
			key=key+null+"_";
		}
		if(StringUtils.isNotBlank(paramMap.get("zdMaterSpec")+"")){
			zdScs.addCondition("zd006MaterialsSpec", paramMap.get("zdMaterSpec")+"", SearchCondition.OP_EQUAL);
			key=key+paramMap.get("zdMaterSpec")+"_";
		}else{
			key=key+null+"_";
		}
		if(StringUtils.isNotBlank(paramMap.get("zdMaterColor")+"")){
			zdScs.addCondition("zd008MaterialsColor", paramMap.get("zdMaterColor")+"", SearchCondition.OP_EQUAL);
			key=key+paramMap.get("zdMaterColor")+"_";
		}else{
			key=key+null+"_";
		}
		if(StringUtils.isNotBlank(paramMap.get("zdMaterQuanlity")+"")){
			zdScs.addCondition("zd008MaterialsQuanlity", paramMap.get("zdMaterQuanlity")+"", SearchCondition.OP_EQUAL);
			key=key+paramMap.get("zdMaterQuanlity");
		}else{
			key=key+null;
		}
		List<LogicWarehouseInventoryDO> whMaterList = this.findListByExample(zdScs).getResults();
		if(whMaterList==null||whMaterList.isEmpty()||whMaterList.size()==0){
			return sumQuantity;
		}else{
			for(LogicWarehouseInventoryDO whMater : whMaterList){
				if(whMater==null||StringUtils.isBlank(whMater.getId())){
					continue;
				}
				//id code model spec color quanlity
				String keyStr=(StringUtils.isEmpty(whMater.getZd003MaterialsId())?null:whMater.getZd003MaterialsId())+"_"+
								(StringUtils.isEmpty(whMater.getZd004MaterialsCode())?null:whMater.getZd004MaterialsCode())+"_"+
								(StringUtils.isEmpty(whMater.getZd007MaterialsModel())?null:whMater.getZd007MaterialsModel())+"_"+
								(StringUtils.isEmpty(whMater.getZd006MaterialsSpec())?null:whMater.getZd006MaterialsSpec())+"_"+
								(StringUtils.isEmpty(whMater.getZd008MaterialsColor())?null:whMater.getZd008MaterialsColor())+"_"+
								(StringUtils.isEmpty(whMater.getZd008MaterialsQuanlity())?null:whMater.getZd008MaterialsQuanlity());
				if(!key.equals(keyStr)){
					continue;
				}
				BigDecimal zdQuantity = whMater.getZd009Quantity()==null?BigDecimal.ZERO:whMater.getZd009Quantity();
				//一等
				BigDecimal oneQuantity = whMater.getZd019OneQuantity()==null?BigDecimal.ZERO:whMater.getZd019OneQuantity();
				//次品
				BigDecimal twoQuantity = whMater.getZd016DefectiveQuantity()==null?BigDecimal.ZERO:whMater.getZd016DefectiveQuantity();
				//旧件
				BigDecimal oldQuantity = whMater.getZd017OldPartsQuantity()==null?BigDecimal.ZERO:whMater.getZd017OldPartsQuantity();
				//冻结
				BigDecimal blockQuantity = whMater.getZd010BlockedStockQuantity()==null?BigDecimal.ZERO:whMater.getZd010BlockedStockQuantity();
				//在途
				BigDecimal traveQuantity = whMater.getZd011TravelingQuantity()==null ?BigDecimal.ZERO:whMater.getZd011TravelingQuantity();
				sumQuantity = sumQuantity.add(zdQuantity.add(oneQuantity).add(twoQuantity).add(oldQuantity).add(blockQuantity).add(traveQuantity));
			}
			return sumQuantity;
		}
	}
	
	@Override
	public void exportExcel(SearchConditions scs, HttpServletResponse response, boolean isShowMoney) throws SyBaseException {
		
		SearchResult result = this.findForWareHouseStockByExample(scs);
		List<LogicWarehouseInventoryDO> list = result.getResults();
		String row = "物料编码:code┋物料名称:name┋物料类型:maType┋型号:spec┋单位:unit┋仓库:whName┋批次:batch┋总库存:sumQuantity┋一等数量:ydengquantity┋次品数量:quantity1┋旧件数量:quantity2┋冻结数量:hgquantity┋在途数量:bhgquantity";
		ExcelUtil.toExcel(list,row,"库存列表导出",response);
	}

	@Override
	public List<String> findbatch(Map map) throws SyBaseException {
//		return logicWarehouseInventoryDAO.findbatch(map);
		return null;
	}

	@Override
	public List<LogicWarehouseInventoryDO> findMaterialsByBatchAll(Map<String, Object> map) throws SyBaseException {
//		return logicWarehouseInventoryDAO.findByBatchAll(map);
		return null;
	}
	@Override
	public List<LogicWarehouseInventoryDO> findMaterialsBySearchBatch(SearchConditions scs) throws SyBaseException {
//		return logicWarehouseInventoryDAO.findBySearchBatch(scs);
		return null;
	}

	@Override
	public Integer deleteBizRemoved(String id) throws SyBaseException {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public List<LogicWarehouseInventoryDO> findWareHouseStockByMap(Map<String, Object> paramMap)throws SyBaseException{
		return logicWarehouseInventoryDAO.findWareHouseStockByMap(paramMap);
	}
	
	@Override
	public SearchResult findSingleStockToBackSel(SearchConditions scs)throws SyBaseException{
		SearchResult rs = new SearchResult(scs);
		List<LogicMaterialBackBillTypeSelVO>  list=logicWarehouseInventoryDAO.findSingleStockToBackSel(scs);
		rs.setRecordCount(logicWarehouseInventoryDAO.countSingleStockToBackSel(scs));
		rs.setResults(list);
		return rs;
	}

	@Override
	public Integer deleteWarehouseInventoryByMap(Map<String, Object> paramMap)
			throws SyBaseException {
		return logicWarehouseInventoryDAO.deleteWarehouseInventoryByMap(paramMap);
	}
	
}
